package org.mspring.mlog.web.module.admin;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.mspring.mlog.entity.Attachment;
import org.mspring.mlog.service.AttachmentService;
import org.mspring.mlog.service.exception.StorageException;
import org.mspring.mlog.web.support.log.Log;
import org.mspring.platform.utils.RequestUtils;
import org.mspring.platform.utils.StringUtils;
import org.mspring.platform.utils.http.HttpUtils;
import org.mspring.platform.web.ResponseEntity;
import org.mspring.platform.web.freemarker.widget.stereotype.Widget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.fastjson.JSON;

/**
 * @author Gao Youbo
 * @since 2012-11-22
 */
@Widget
@RequestMapping("/admin/attachment")
public class Admin_AttachmentWidget extends Admin_AbstractWidget {

    private static final Logger log = LoggerFactory.getLogger(Admin_AttachmentWidget.class);

    @Autowired
    private AttachmentService attachmentService;

    @ResponseBody
    @RequestMapping("/upload")
    @Log
    public String upload(@RequestParam(required = false) Long fid, HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            if (fileMap == null || fileMap.size() < 1) {
                return null;
            }
            MultipartFile mf = null;
            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                mf = entity.getValue();
                break;
            }
            long id = attachmentService.insert(mf.getBytes(), Attachment.AttachFrom.FROM_POST, fid);
            Attachment attachment = attachmentService.get(id);
            return JSON.toJSONString(attachment);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @RequestMapping("/dialog")
    public String uploadDialog(HttpServletRequest request, HttpServletResponse response, Model model) {
        return "/admin/attachment/dialog";
    }

    @RequestMapping("/uploadview")
    public String upload_view(@RequestParam(required = false) Long post, HttpServletRequest request, HttpServletResponse response, Model model) {
        model.addAttribute("post", post);
        return "/admin/attachment/uploadview";
    }

    @RequestMapping("/attachments")
    public String attachments(@RequestParam(required = false) Long post, HttpServletRequest request, HttpServletResponse response, Model model) {
        List<Attachment> attachments = attachmentService.listAttachmentsByForeign(Attachment.AttachFrom.FROM_POST, post);
        model.addAttribute("attachments", attachments);
        model.addAttribute("post", post);
        return "/admin/attachment/attachments";
    }

    @RequestMapping("/delete")
    @ResponseBody
    public String delete(@RequestParam(required = false) Long id, HttpServletRequest request, HttpServletResponse response, Model model) {
        try {
            attachmentService.delete(id);
        } catch (Exception e) {
            return "false";
        }
        return "true";
    }

    /**
     * 下载远程图片
     *
     * @param request
     * @param response
     * @param model
     * @return
     * @throws Exception
     */
    @RequestMapping("/remote")
    @ResponseBody
    public ResponseEntity downloadRemoteImages(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
        Long fid = RequestUtils.getRequestParameterAsLong(request, "fid");
        String ftype = RequestUtils.getRequestParameterAsString(request, "ftype");
        String content = RequestUtils.getRequestParameterAsString(request, "content");

        ResponseEntity rsp = new ResponseEntity();
        if (fid == null || StringUtils.isBlank(ftype)) {
            rsp.setSuccess(false);
            rsp.setMessage("fid、ftype未设置正确");
            return rsp;
        }
        if (StringUtils.isBlank(content)) {
            rsp.setSuccess(true);
            rsp.put("content", content);
            return rsp;
        }

        // 处理附件图片
        Document doc = Jsoup.parse(content);
        Elements images = doc.select("img");
        for (Element image : images) {
            String src = image.attr("src");
            try {
                HttpResponse httpResponse = HttpUtils.get(src, null, -1, src);
                if (httpResponse.getStatusLine().getStatusCode() != 200) {
                    log.error("fetch image error, http_code={}, URL={}", httpResponse.getStatusLine().getStatusCode(), src);
                    continue;
                }
                long id = attachmentService.create(httpResponse.getEntity().getContent(), ftype, fid);
                Attachment attachment = attachmentService.get(id);
                image.attr("src", attachment.getUrl());
            } catch (IOException | IllegalStateException | URISyntaxException | StorageException e) {
                log.error(e.getMessage(), e);
                continue;
            }
            Element imageParent = image.parent();
            if (imageParent != null && "a".equals(imageParent.tagName())) { // 如果Image的父标签为链接地址，去掉链接
                imageParent.replaceWith(image);
            }
        }
        rsp.setSuccess(true);
        rsp.put("content", doc.html());
        return rsp;
    }
}
